//
//  CameraOption.swift
//  videoPlayerSwift
//
//  Created by xwl on 2019/3/5.
//  Copyright © 2019年 xuwanliang. All rights reserved.
//

import AVFoundation
import UIKit

protocol CameraCaptureDelegate {
    func setResolution(width: Int, height: Int)
    func captureBuffer(_ sampleBuffer:CMSampleBuffer!)
}

class CameraOption: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate{
    
    var delegate:CameraCaptureDelegate? = nil
    var session: AVCaptureSession!
    var device: AVCaptureDevice!
    var output: AVCaptureVideoDataOutput!
    var cameraPosition = AVCaptureDevice.Position.front
    
    required init(_ delegate: CameraCaptureDelegate) {
        super.init()
        self.delegate = delegate
        prepareCamera()
    }
    
    deinit {
        if let sess = self.session, sess.isRunning{
            sess.stopRunning()
        }
    }
    
    public func startRuning(){
        if let sess = self.session{
            if !sess.isRunning{
                sess.startRunning()
            }
        }
    }
    public func stopRuning(){
        if let sess = self.session{
            if sess.isRunning{
                sess.stopRunning()
            }
        }
    }
    private func prepareCamera() {
        // Prepare a video capturing session.
        self.session = AVCaptureSession()
        self.session.sessionPreset = AVCaptureSession.Preset.vga640x480 // not work in iOS simulator
        self.device = AVCaptureDevice.default(.builtInWideAngleCamera, for: AVMediaType.video, position: cameraPosition)
        if (self.device == nil) {
            print("no device")
            return
        }
        do {
            let input = try AVCaptureDeviceInput(device: self.device)
            self.session.addInput(input)
        } catch {
            print("no device input")
            return
        }
        self.output = AVCaptureVideoDataOutput()
        self.output.videoSettings = [ kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) ]
        
        let queue: DispatchQueue = DispatchQueue(label: "videocapturequeue", attributes: [])
        self.output.setSampleBufferDelegate(self, queue: queue)
        self.output.alwaysDiscardsLateVideoFrames = true
        
        
        if self.session.canAddOutput(self.output) {
            self.session.addOutput(self.output)
        } else {
            print("could not add a session output")
            return
        }
        do {
            try self.device.lockForConfiguration()
            self.device.activeVideoMinFrameDuration = CMTimeMake(value: 1, timescale: 20) // 20 fps
            self.device.unlockForConfiguration()
        } catch {
            print("could not configure a device")
            return
        }
        self.output.connection(with: .video)?.videoOrientation = .landscapeRight
        print("camera inited!!")
    }
    
    func captureOutput(_ captureOutput: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
        delegate?.captureBuffer(sampleBuffer)

    }
}
